class Promise {

//声明 『构造函数』
  constructor (executor){
    const self = this ;
    // 添加属性
    self.promiseStatus = 'pending';
    self.promiseResult = undefined;

    // 通过callbacks数组可以保存多个回调
    self.callbacks = []

    function resolve(value) {
      // promise的状态只能 从pending改变为rejected/fulfilled状态，只能改变一次
      if(self.promiseStatus !== 'pending') return ;
      self.promiseStatus = 'fulfilled'; // resolved
      self.promiseResult = value

      // 依次执行每个回调
      self.callbacks.forEach(item => {
        item.onResolved(self.promiseResult)
      })
    }

    function reject(reason) {
      if(self.promiseStatus !== 'pending') return ;
      self.promiseStatus = 'rejected';
      self.promiseResult = reason

      self.callbacks.forEach(item => {
        item.onRejected(self.promiseResult)
      })
    }

    try {
      executor(resolve, reject);
    }catch(err) {
      reject(err)
    }
  }


	// 原型对象上 添加 then方法
  then (onResolved, onRejected) {
    const self = this

    if(typeof onResolved !== 'function') {
      onResolved = value => value
    }
    if(typeof onRejected !== 'function') {
      onRejected = reason => {
        throw reason
      }
    }

    return new Promise((resolve, reject) => {
      function callback(onTypeFn) {
        try{
          let ret = onTypeFn(self.promiseResult)
          if(ret instanceof Promise) {
            ret.then(v => resolve(v), r => reject(r))
          } else {
            resolve(ret)
          }
        } catch(err) {
          reject(err)
        }
      }

      // resolve/reject改变promise的状态后，
      // 会执行 then方法中的 onResolved/onRejected 回调
      if(self.promiseStatus === 'fulfilled') {
        setTimeout(() => {
          callback(onResolved)
        })
      }

      if(self.promiseStatus === 'rejected') {
        setTimeout(() => {
          callback(onRejected)
        })
      }

      // pending状态是，需要保存回调函数，等到promise状态改变后进行回调
      if(self.promiseStatus === 'pending') {
        // 返回值是在Promise构造函数遍历callbacks时才能获取到，
        // 嵌套一层函数, 而不是直接将onResolved/onRejected 交由Promise构造函数执行
        self.callbacks.push({
          onResolved: function (data) {
            setTimeout(() => {
              console.log('data', data === self.promiseResult, self.promiseResult, data)
              callback(onResolved)
            })

          },
          onRejected: function (reason) {
            setTimeout(() => {
              console.warn('reason', reason === self.promiseResult, self.promiseResult, reason)
              callback(onRejected)
            })
          }
        })
      }
    });

  };

  catch(onReject){
  	return this.then(undefined, onReject)
	}


	// ++++++++++++++++  构造函数对象上的方法， 静态方法, 返回promise对象 ++++++++++++++++
	// 如果传入的参数为 非Promise类型的对象, 则返回的结果为成功promise对象
	// 如果传入的参数为 Promise 对象, 则参数的结果决定了 resolve 的结果
	static resolve (value) {
    return new Promise((resolve, reject) => {
      if(value instanceof Promise) {
        value.then(v => resolve(v), r => reject(r))
      } else {
        resolve(value)
      }
    })
  }
	// 始终返回失败的promise
  static reject (reason) {
    return new Promise((resolve, reject) => {
      reject(reason)
    })
  }

  // 所有请求都成功，才会返回成功的promise
  static all (promiseList) {
    var results = []
    return new Promise((resolve, reject) => {
      var cnt = 0;
      promiseList.forEach((promise, index) => {
        promise.then(value => {
          results[index] = value
          if(++cnt === list.length) {
            resolve(results)
          }
        }, reason => {
          reject(reason)
        })

      })
    })
	}

  // 只要有一个成功该返回的promise 就算成功
  static one (promiseList) {
    var results = []
    var faileds = []
    return new Promise((resolve, reject) => {
      var failedCnt = 0;
      promiseList.forEach((promise, index) => {
        promise.then(value => {
          results.push(value)
        }, reason => {
          faileds[index] = reason
					// 全部失败才算失败
          if(++failedCnt === list.length) {
            reject(faileds)
          }
        })
      })
      resolve(results)
    })
	}

  // race 赛跑， 返回最先改变状态的promise, 可能成功也可能失败
  static race (promiseList) {
    return new Promise((resolve, reject) => {
      promiseList.forEach(promise => {
        promise.then(value => {
          //修改返回对象的状态为 『成功』
          resolve(value)
        }, reason => {
          // 修改返回对象的状态为 『失败』
          reject(reason)
        })
      })
    })
	}


}
